/*
 * name: countdown.js
 * version: v0.1.1
 * update: 修复多组倒计时冲突bug；代码待整理！
 * data: 2014-12-04
 * author: https://github.com/rendro/countdown
 */
define(function(require, exports, module) {
	var defaultOptions = {
		begin: new Date(),
		date: "June 7, 2087 15:03:25",
		refresh: 1000,
		offset: 0,
		onEnd: function() {
			return;
		},
		render: function(date) {
			this.innerHTML = date.years + " 年, " +
				date.days + " 天, " +
				this.leadingZeros(date.hours) + " 时, " +
				this.leadingZeros(date.min) + " 分 " +
				this.leadingZeros(date.sec) + " 秒";
		}
	};

	/**
	 * Countdown constructor
	 * @param {HTMLElement} el      DOM node of the countdown
	 * @param {Object}      options (optional) Options for the plugin
	 */
	var Countdown = function(el, options) {
		console.log(el)

		/**
		 * Options of the countdown plugin
		 * @type {Object}
		 */
		el.options = {};

		/**
		 * Interval reference or false if counter is stopped
		 * @type {Mixed}
		 */
		el.interval = false;

		// merge default options and options into this.options
		for (var i in defaultOptions) {
			if (defaultOptions.hasOwnProperty(i)) {
				el.options[i] = typeof options[i] !== 'undefined' ? options[i] : defaultOptions[i];

				if (i === 'date' && typeof el.options.date !== 'object') {
					el.options.date = new Date(el.options.date);
				}

				// bind context for functions
				if (typeof el.options[i] === 'function') {
					el.options[i] = el.options[i].bind(el);
				}
			}
		}

		el.startServer = el.options.begin;
		el.startLocal = Date.now();

		/**
		 * Get the difference between now and the end date
		 * @return {Object} Object with the diff information (years, days, hours, min, sec, millisec)
		 */
		el.getDiffDate = function() {
			var now = Date.now();
			var difftime = now - el.startLocal;
			el.startServer.setMilliseconds(el.startServer.getMilliseconds() + difftime);
			el.startLocal = now;
			var diff = (el.options.date.getTime() - el.startServer + el.options.offset) / 1000;

			var dateData = {
				years: 0,
				days: 0,
				hours: 0,
				min: 0,
				sec: 0,
				millisec: 0
			};

			if (diff <= 0) {
				if (el.interval) {
					el.stop();
					el.options.onEnd();
				}
				return dateData;
			}

			if (diff >= (365.25 * 86400)) {
				dateData.years = Math.floor(diff / (365.25 * 86400));
				diff -= dateData.years * 365.25 * 86400;
			}

			if (diff >= 86400) {
				dateData.days = Math.floor(diff / 86400);
				diff -= dateData.days * 86400;
			}

			if (diff >= 3600) {
				dateData.hours = Math.floor(diff / 3600);
				diff -= dateData.hours * 3600;
			}

			if (diff >= 60) {
				dateData.min = Math.floor(diff / 60);
				diff -= dateData.min * 60;
			}

			dateData.sec = Math.round(diff);

			dateData.millisec = diff % 1 * 1000;
			return dateData;
		}.bind(el);

		/**
		 * Add leading zeros to a number
		 * @param  {Number} num    Input number
		 * @param  {Number} length Length of the desired output
		 * @return {String}        String of the desired length with leading zeros
		 */
		el.leadingZeros = function(num, length) {
			length = length || 2;
			num = String(num);
			if (num.length > length) {
				return num;
			}
			return (Array(length + 1).join('0') + num).substr(-length);
		};

		/**
		 * Update the end date of the countdown
		 * @param  {Mixed}     newDate Date object or a String/Number that can be passed to the Date constructor
		 * @return {Countdown}         Countdown instance
		 */
		el.update = function(newDate) {
			if (typeof newDate !== 'object') {
				newDate = new Date(newDate);
			}
			el.options.date = newDate;
			el.render();
			return el;
		}.bind(el);

		/**
		 * Stop the countdown refresh / rerender
		 * @return {Countdown} Countdown instance
		 */
		el.stop = function() {
			if (el.interval) {
				clearInterval(el.interval);
				el.interval = false;
			}
			return el;
		}.bind(el);

		/**
		 * Render the countdown
		 * @return {Countdown} Countdown instance
		 */
		el.render = function() {
			el.options.render(el.getDiffDate());
			return el;
		}.bind(el);

		/**
		 * Start the countdown
		 * @return {Countdown} Countdown instance
		 */
		el.start = function() {
			// don't start if the countdown is already started
			if (el.interval) {
				return;
			}

			el.render();

			if (el.options.refresh) {
				el.interval = setInterval(el.render, el.options.refresh);
			}

			return el;
		}.bind(el);

		/**
		 * Update the offset
		 * @param  {Number}    offset New offset in ms
		 * @return {Countdown}        Countdown instance
		 */
		el.updateOffset = function(offset) {
			el.options.offset = offset;
			return el;
		}.bind(el);


		// initial start of the countdown or initial render
		el.start();
	};

	module.exports = Countdown;

});